﻿using Tesla.Bounding;
using Tesla.Content;
using Tesla.Graphics;
using Tesla.Math;
using Tesla.Scene;
using Tesla.Scene.Extension;
using Tesla.Scene.Shape;

namespace TeslaSamples.Pipeline {
    [AppDescription("DXS Model Loading", PlatformCapabilities.Direct3D10 | PlatformCapabilities.XNA4, "DxsModelLoadingImage", "DxsModelLoadingDesc", "DxsModelLoadingSource")]
    public class DxsModelLoading : BasicApp {
        protected override void LoadContent() {
            Window.Title = "DXS Model Loading Sample";
            Renderer.CurrentCamera.Position = new Vector3(-70, 90, 120);
            Renderer.CurrentCamera.LookAt(new Vector3(0, 0, 0), Vector3.Up);
            Renderer.CurrentCamera.Update();

            //When calling ContentManager.Load<T>(), an optional loader parameter can be passed that tells the content importer
            //how to process the content. Model loaders take ModelLoaderParameters and image loaders take ImageLoaderParameters. They
            //can be re-used.
            //
            //In this case, we have to tell the model loader that we want to swap the winding order of polygons so we do not get
            //incorrect rendering. Other options include the angle at which to rotate the model about the XYZ axes, how normals should
            //be generated (if any), if a tangent basis should be generated, where to find textures, or overload material creation by
            //supplying a material to load and use as a template.
            ModelLoaderParameters mlp = new ModelLoaderParameters();
            mlp.SwapWindingOrder = true;
            mlp.PreferLitMaterials = false;

            //In BasicApp, we registered a DXSModelLoader to the content manager, if we didn't this will throw
            //an exception that we do not have a means to handle the requested content. Loaders are designated by
            //both the runtime type and the content file extension.
            //
            //Notice with loading this model, we use Spatial rather than Mesh, because a model may be in fact a
            //scene graph with multiple parts. We can either have a Node or Mesh returned. In this case,
            //we should have a mesh returned since the model is a single mesh in the file. If the model
            //used two different materials, it would have to be split up into two different meshes
            //and then attached to a Node that would be returned, for example.
            Spatial model = ContentManager.Load<Spatial>("Models//station.dxs", mlp);
            model.AddController(new RotateController(Vector3.Up, 5));
            model.SetModelBound(new BoundingBox());
            RootNode.AddChild(model);

            Box sky = new Box("Space", Vector3.Zero, 100, 100, 100);
            sky.SceneHints.RenderBucketType = RenderBucketType.PreBucket;
            sky.Material = ContentManager.Load<Material>("Materials//SpaceSkybox.tem");

            RootNode.AddChild(sky);
        }
    }
}
